import sys,os
import struct


dsw_flash_partition_table_16M_0 = {
    'mtd_nsboot': 0x10000,
    'mtd_uboot' : 0x50000,
    'mtd_kernel' : 0x3a0000,
    'mtd_fs': 0x400000,
    'mtd_cfg': 0x100000,
    'mtd_app0' : 0x380000,
    'mtd_app1' : 0x380000,
    'mtd_all': 0x1000000,
}

dsw_flash_partition_table_16M_1 = {
    'mtd_nsboot': 0x10000,
    'mtd_uboot' : 0x50000,
    'mtd_kernel' : 0x260000,
    'mtd_fs': 0x340000,
    'mtd_cfg': 0x100000,
    'mtd_app0' : 0x480000,
    'mtd_app1' : 0x480000,
    'mtd_all': 0x1000000,
}

dsw_flash_partition_table_32M = {
    'mtd_nsboot': 0x10000,
    'mtd_uboot' : 0x50000,
    'mtd_kernel' : 0x260000,
    'mtd_fs': 0x340000,
    'mtd_cfg': 0x1100000,
    'mtd_app0' : 0x480000,
    'mtd_app1' : 0x480000,
    'mtd_all': 0x2000000,
}

dsw_flash_partition_table_64M = {
    'mtd_nsboot': 0x10000,
    'mtd_uboot' : 0x60000,
    'mtd_kernel' : 0x390000,
    'mtd_fs': 0x400000,
    'mtd_cfg': 0x2e00000,
    'mtd_app0' : 0x500000,
    'mtd_app1' : 0x500000,
    'mtd_all': 0x4000000,
}

dsw_flash_storage_table = {
    '16M': 0x1000000,
    '32M': 0x2000000,
    '64M': 0x4000000,
}

dsw_dev_type_table = {
    3  : ['SKD2618',dsw_flash_partition_table_16M_0],
    4  : ['SKD271XA',dsw_flash_partition_table_16M_0],
    5  : ['SKD271XA',dsw_flash_partition_table_16M_0],
    6  : ['SKD271XA',dsw_flash_partition_table_16M_0],
    7  : ['SKD271XA',dsw_flash_partition_table_16M_0],
    8  : ['SKD271XA',dsw_flash_partition_table_16M_0],

    10 : ['SKD272XA',dsw_flash_partition_table_16M_0],
    11 : ['SKD272XA',dsw_flash_partition_table_16M_0],
    12:  ['SKD272XA',dsw_flash_partition_table_16M_0],
    13:  ['SKD272XA',dsw_flash_partition_table_16M_0],
    14:  ['SKD272XA',dsw_flash_partition_table_16M_0],

    16: ['SKD201XA',dsw_flash_partition_table_16M_0],
    17: ['SKD201XA',dsw_flash_partition_table_16M_0],
    18: ['SKD201XA',dsw_flash_partition_table_16M_0],
    19: ['SKD201XA',dsw_flash_partition_table_16M_0],
    20: ['SKD201XA',dsw_flash_partition_table_16M_0],

    50: ['SKD3000M',dsw_flash_partition_table_64M],

    51: ['SKD301XB(ISDB-T)',dsw_flash_partition_table_16M_1],
    53: ['SKD301XB(DVB-T)',dsw_flash_partition_table_16M_1],
    54: ['SKD301XA(DTMB)',dsw_flash_partition_table_16M_1],
    71: ['SKD301XA(DVB-C)',dsw_flash_partition_table_16M_1],
    72: ['SKD301XA(DVB-T)',dsw_flash_partition_table_16M_1],
    73: ['SKD301XA(ATSC)',dsw_flash_partition_table_16M_1],
    74: ['SKD301XA(J83B)',dsw_flash_partition_table_16M_1],

    90: ['SKD305X',dsw_flash_partition_table_16M_0],
    91: ['SKD305X',dsw_flash_partition_table_16M_0],
    92: ['SKD305X',dsw_flash_partition_table_16M_0],
    93: ['SKD305X',dsw_flash_partition_table_16M_0],
    94: ['SKD305X',dsw_flash_partition_table_16M_0],

    95: ['SKD3050',dsw_flash_partition_table_16M_0],
    96: ['SKD1550',dsw_flash_partition_table_16M_0],
    97: ['SKD1550B',dsw_flash_partition_table_16M_0],
    98: ['SKD2150', dsw_flash_partition_table_16M_0],
    99: ['SKD2150B', dsw_flash_partition_table_16M_0],

    120: ['SKD305XB',dsw_flash_partition_table_16M_0],
    121: ['SKD305XB',dsw_flash_partition_table_16M_0],
    122: ['SKD305XB',dsw_flash_partition_table_16M_0],
    123: ['SKD305XB',dsw_flash_partition_table_16M_0],
    124: ['SKD305XB',dsw_flash_partition_table_16M_0],

    200: ['SKD1900M',dsw_flash_partition_table_64M],
    201: ['SKD3010B',dsw_flash_partition_table_16M_1],
    400: ['SKD1500M',dsw_flash_partition_table_32M],
    1200:['SKD2160',dsw_flash_partition_table_16M_0],
    1205:['SKD2170',dsw_flash_partition_table_16M_0],

    # 9  : ['SKD296x',dsw_flash_partition_table_16M_0],
    # 2 : ['SKD2036C',dsw_flash_partition_table_16M_0],
    # 251:['SKD2810',dsw_flash_partition_table_16M_0],
}
update_file_head_size=280
outputfile='mtd_app.bin'
# typedef struct{
#     int nFirmwareType;
#     int nFileType;
#     int nFileLen;
#     int nDevType;
#     int nbuildTimestamp;
# //    char sHardVersion[256];
# 	char sHardVersion[4][64];
#     int nCheckSum;
#     unsigned char nData[0];
# } ST_UPDATE_FILEHEAD_T, *LPST_UPDATE_FILEHEAD_T;

MTDn='mtd_nsboot.bin'
#uboot+env
MTD0='mtd_uboot.bin'
#kernel
MTD1='mtd_linux.bin'
#filesystem
MTD2='mtd_fs.bin'
#用户配置文件信息
MTD3='mtd_cfg.bin'
#应用程序
MTD4='mtd_app.bin'
MTD5='mtd_app.bin'
MTD6='all.img'

def dsw_prase_upgrade_file_head(filepath):
    with open(filepath, 'rb') as fd:
        fd.seek(0,2)
        if fd.tell() < update_file_head_size:
            return -1
        else:
            fd.seek(0, 0)
        head = fd.read(update_file_head_size)
        nFirmwareType, nFileType, nFileLen, nDevType, nbuildTimestamp, sHardVersion0, sHardVersion1, sHardVersion2, sHardVersion3, nCheckSum = struct.unpack(
            '5I64s64s64s64sI', head)
        return nDevType,nbuildTimestamp,sHardVersion0,sHardVersion1,sHardVersion2,sHardVersion3

def dsw_create_mtd_app_bin(filepath,mtdAppSize):
    with open(filepath, 'rb') as fd:
        print('file check done, drop the update header.')
        with open(outputfile, 'wb') as fd1:
            fd.seek(280, 0)
            while True:
                str = fd.read(1024)
                if str == b"":
                    break
                fd1.write(str)
            s = struct.pack('B', 0xff)
            if fd1.tell() < mtdAppSize:
                for i in range(mtdAppSize - fd1.tell()):
                    fd1.write(s)
            print('create file',outputfile)


def tag_flash_file():
    if os.path.exists(MTD6):
        print('remove %s' % MTD6)
        os.remove(MTD6)

    file_array=[MTDn,MTD0,MTD1,MTD2,MTD3,MTD4,MTD4]
    with open(MTD6,'ab') as fmerge:
        for f in file_array:
            with open(f,"rb") as fd:
                print('load file %s' % f)
                data = fd.read()
                fmerge.write(data)
                print(fmerge.tell()/1024)

def update_old_flash(dev_type, old_file, upgrade_file, output_file):
    mtd_nsboot=dsw_dev_type_table[dev_type][1]['mtd_nsboot']
    mtd_uboot = dsw_dev_type_table[dev_type][1]['mtd_uboot']
    mtd_kernel = dsw_dev_type_table[dev_type][1]['mtd_kernel']
    mtd_fs = dsw_dev_type_table[dev_type][1]['mtd_fs']
    mtd_cfg = dsw_dev_type_table[dev_type][1]['mtd_cfg']
    mtd_app = dsw_dev_type_table[dev_type][1]['mtd_app0']
    mtd_all = dsw_dev_type_table[dev_type][1]['mtd_all']
    dsw_create_mtd_app_bin(upgrade_file,mtd_app)

    with open(old_file, 'rb') as fd:
        fd.seek(0,2)
        if fd.tell() != mtd_all:
            print('file size not match ',mtd_all)
            return False
        else:
            fd.seek(0, 0)
        need_size=mtd_nsboot+mtd_uboot+mtd_kernel+mtd_fs+mtd_cfg
        with open(output_file, 'wb') as fd1:
            while True:
                str = fd.read(1024)
                fd1.write(str)
                if fd.tell() == need_size:
                    print('already read %d bytes'%need_size)
                    break
            with open(MTD4, "rb") as fd2:
                fd1.write(fd2.read())
                fd2.seek(0, 0)
                fd1.write(fd2.read())

# check_upgrade_file('up_V20211229111033_SKD201XA_V4.squashApp.img')
# tag_flash_file()
# update_old_flash('flash_SKD201XA_V4_0_20211229.bin','all.img','16M')
# import time
# result=check_upgrade_file('up_V20211229111033_SKD201XA_V4.squashApp.img')
# timeArray = time.localtime(result[0])
# otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
# print('upgrade file date:',otherStyleTime)

# print(str(result[1], 'utf-8').strip())
# ver=filter(str.isalnum, str(result[1], 'utf-8'))
# print(list(ver))

# ver=str(result[1], 'utf-8')
# print(ver.strip('\0'))
# print(dsw_dev_type_table[4][1]['mtd_nsboot'])